﻿using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Intentions.Extensibility.Menu;
using JetBrains.ReSharper.Psi.CSharp;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.Util;
using MugenMvvmToolkit.ReSharper.Highlighting;
using MugenMvvmToolkit.ReSharper.Infrastructure;
using MugenMvvmToolkit.ReSharper.ViewModels.ContextActions;

namespace MugenMvvmToolkit.ReSharper.ViewModels.QuickFixes
{
    [QuickFix]
    public class MismatchModelPropertyNameFix : IQuickFix
    {
        #region Fields

        private readonly MismatchModelPropertyNameHighlighting _highlighting;

        #endregion

        #region Constructors

        public MismatchModelPropertyNameFix([NotNull] MismatchModelPropertyNameHighlighting highlighting)
        {
            if (highlighting == null) throw new ArgumentNullException("highlighting");
            _highlighting = highlighting;
        }

        #endregion

        #region Implementation of IQuickFix

        public IEnumerable<IntentionAction> CreateBulbItems()
        {
            return new IBulbAction[]
            {
                new DelegateBulbAction((solution, indicator) => Execute(true), UiResources.AddModelPropertyAttribute),
                new DelegateBulbAction((solution, indicator) => Execute(false), UiResources.AddIgnorePropertyAttribute)
            }.ToQuickFixAction();
        }

        /// <summary>
        ///     Check if this action is available at the constructed context.
        ///     Actions could store precalculated info in <paramref name="cache" /> to share it between different actions
        /// </summary>
        /// <returns>
        ///     true if this bulb action is available, false otherwise.
        /// </returns>
        public bool IsAvailable(IUserDataHolder cache)
        {
            return _highlighting.IsValid();
        }

        #endregion

        #region Methods

        private void Execute(bool isModelAttribute)
        {
            TypeProvider typeProvider = TypeProvider.Create(_highlighting.ClassLikeDeclaration.GetPsiModule(), _highlighting.ClassLikeDeclaration.GetResolveContext());
            CSharpElementFactory elementFactory = CSharpElementFactory.GetInstance(typeProvider.PsiModule, true);
            if (isModelAttribute)
                ModelPropertyAttributeAction
                    .AddModelPropertyAttribute(elementFactory, typeProvider, _highlighting.PropertyDeclaration,
                        _highlighting.ModelProperty.ShortName);
            else
                IgnorePropertyAttributeAction.AddIgnorePropertyAttribute(elementFactory, typeProvider,
                    _highlighting.PropertyDeclaration);
        }

        #endregion
    }
}